package cn.lix.nio.demo.test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

public class NioServer {

    public static void main(String[] args) throws IOException {
        // 创建一个selector等待事件
        Selector selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 绑定监听端口
        serverSocketChannel.socket().bind(new InetSocketAddress(9999));
        // 设置非阻塞
        serverSocketChannel.configureBlocking(false);
        // 注册事件驱动。如果接到任务就开始工作
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        for (; ; ) {
            // 这里假如200ms等待是否接收到任务，没有就再看看是否有任务
            if (selector.select(200) == 0) {
//                System.out.println("===========继续等待=========");
                continue;
            }
            // 如果拿到任务排队
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            for (Iterator<SelectionKey> it = selectionKeys.iterator(); it.hasNext(); ) {
                // 给任务分一个key，任务需要那这个key去等待处理
                SelectionKey selectionKey = it.next();
                if(selectionKey.isAcceptable()){
                    System.out.println("接收到数据。。。。。。");
                    // 反向拿到客户端连过来的channel
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    // 给channel注册一个事件驱动，并交给他一个buffer
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                }
                // 如果任务key类型是可读的
                if(selectionKey.isReadable()){
                    System.out.println("可读数据。。。。。。");
                    SocketChannel channel = (SocketChannel) selectionKey.channel();
                    ByteBuffer buffer = (ByteBuffer) selectionKey.attachment();
                    channel.read(buffer);
                    System.out.println("server:" + new String(buffer.array()));
                }
                // 处理过的key需要删除，不然会重复处理
                it.remove();
            }
        }
    }
}
